// 基于axios封装网络请求
import theAxios from 'axios'
import router from '@/router'
import { removeStorage } from '@/utils/storage.js'
import Notify from '@/ui/Notify.js'
import { getToken, setToken, removeToken } from '@/utils/token.js'
import { refreshTokenAPI } from '@/api'
import store from '@/store/index.js'

const axios = theAxios.create({
  baseURL: 'http://geek.itheima.net', // 基地址 http://toutiao.itheima.net http://geek.itheima.net
  timeout: 20000 // 请求20秒无响应，判定超时
})

// 添加请求拦截器
axios.interceptors.request.use(function(config) {
  // 统一携带token
  // 判断本地有token再携带，判断具体api/index.js里如果没有携带Authorization，我再添加上去
  if (getToken()?.length > 0 && config.headers.Authorization === undefined) {
    config.headers.Authorization = `Beraer ${getToken()}`
  }
  return config
}, function(error) {
  // 对请求错误做些什么
  return Promise.reject(error)
})

// 添加响应拦截器
axios.interceptors.response.use(function(response) {
  // http 相应状态码为2xx、3xx就进入这里
  return response
}, async function(error) {
  // http 相应状态码为4xx、5xx报错就进入这里

  // 401为身份过期
  if (error.response.status === 401) {
    // 清除token
    removeToken()
    // 使用refreshToken请求新token再继续使用，不用返回登录页面
    const { data: res } = await refreshTokenAPI()
    setToken(res.data.token)
    // 用refreshToken重新请求新的tonken
    error.config.headers.Authorization = `Bearer ${res.data.token}`

    return axios(error.config) // 重新发起未完成的请求
  } else if (error.response.status === 500 && error.config.url === '/v1_0/authorizations' && error.config.method === 'put') {
    // 刷新的token也过期了，跳转到登录页面
    Notify({
      type: 'danger',
      message: '身份已过期，请重新登录！'
    })

    // 把user页面变为不缓存状态，刷新里面的数据
    store.dispatch('addExculdeCacheView', 'User')

    // 清空刷新用的token 重新返回登录页面
    removeStorage('refresh_token')

    // router.currentRoute 相当于 在vue文件内this.$route -> 当前路对象的信息 (router.currentRoute === this.$route)
    // fullpath 路由对象里完整的路由路径 #后面的一切
    // 跳转登录页面，并且把跳转前的path地址记录下来
    router.replace(`/login?path=${router.currentRoute.fullPath}`)
  }

  return Promise.reject(error)
})

export default ({ url, method = 'GET', params = {}, data = {}, headers = {} }) => {
  return axios({ url, method, params, data, headers })
}

/* 上面有局限性，导出的axios方法在使用时
  我在逻辑页面调用时，传入的这5个配置名字
  万一将来要更新request.js里封装网络请求的工具
  把axios换成jQuery的$.ajax
    axios({
      url: '请求地址',
      method: '请求方法',
      params: {},
      data: {},
      headers:{}
    })
 */
